// Copyright 2024 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

// Code generated by "measure-tape"; DO NOT EDIT.
//
// See tools/fidl/measure-tape/README.md

// clang-format off
#include "hlcpp_measure_tape_for_peer.h"

#include <fuchsia/bluetooth/cpp/fidl.h>
#include <fuchsia/bluetooth/le/cpp/fidl.h>
#include <zircon/types.h>


namespace measure_tape {
namespace fuchsia {
namespace bluetooth {
namespace le {

namespace {

class MeasuringTape {
 public:
  MeasuringTape() = default;

  void Measure(const ::fuchsia::bluetooth::le::AdvertisingData& value) {
    num_bytes_ += 16;
    MeasureOutOfLine(value);
  }

  void MeasureOutOfLine(const ::fuchsia::bluetooth::le::AdvertisingData& value) {
    int32_t max_ordinal = 0;
    if (value.has_name()) {
      num_bytes_ += 16;
      num_bytes_ += FIDL_ALIGN(value.name().length());
      max_ordinal = 1;
    }
    if (value.has_appearance()) {
      max_ordinal = 2;
    }
    if (value.has_tx_power_level()) {
      max_ordinal = 3;
    }
    if (value.has_service_uuids()) {
      num_bytes_ += 16;
      num_bytes_ += FIDL_ALIGN(value.service_uuids().size() * 16);
      max_ordinal = 4;
    }
    if (value.has_service_data()) {
      num_bytes_ += 16;
      for (const auto& service_data_elem : value.service_data()) {
        Measure(service_data_elem);
      }
      max_ordinal = 5;
    }
    if (value.has_manufacturer_data()) {
      num_bytes_ += 16;
      for (const auto& manufacturer_data_elem : value.manufacturer_data()) {
        Measure(manufacturer_data_elem);
      }
      max_ordinal = 6;
    }
    if (value.has_uris()) {
      num_bytes_ += 16;
      for (const auto& uris_elem : value.uris()) {
        num_bytes_ += 16;
        num_bytes_ += FIDL_ALIGN(uris_elem.length());
      }
      max_ordinal = 7;
    }
    if (value.has_include_tx_power_level()) {
      max_ordinal = 8;
    }
    num_bytes_ += 8 * max_ordinal;
  }

  void Measure(const ::fuchsia::bluetooth::le::ManufacturerData& value) {
    num_bytes_ += FIDL_ALIGN(24);
    MeasureOutOfLine(value);
  }

  void MeasureOutOfLine(const ::fuchsia::bluetooth::le::ManufacturerData& value) {
    num_bytes_ += FIDL_ALIGN(value.data.size() * 1);
  }

  void Measure(const ::fuchsia::bluetooth::le::Peer& value) {
    num_bytes_ += 16;
    MeasureOutOfLine(value);
  }

  void MeasureOutOfLine(const ::fuchsia::bluetooth::le::Peer& value) {
    int32_t max_ordinal = 0;
    if (value.has_id()) {
      Measure(value.id());
      max_ordinal = 1;
    }
    if (value.has_connectable()) {
      max_ordinal = 2;
    }
    if (value.has_rssi()) {
      max_ordinal = 3;
    }
    if (value.has_advertising_data()) {
      Measure(value.advertising_data());
      max_ordinal = 4;
    }
    if (value.has_name()) {
      num_bytes_ += 16;
      num_bytes_ += FIDL_ALIGN(value.name().length());
      max_ordinal = 5;
    }
    if (value.has_data()) {
      Measure(value.data());
      max_ordinal = 6;
    }
    if (value.has_bonded()) {
      max_ordinal = 7;
    }
    if (value.has_last_updated()) {
      num_bytes_ += 8;
      max_ordinal = 8;
    }
    num_bytes_ += 8 * max_ordinal;
  }

  void Measure(const ::fuchsia::bluetooth::le::ScanData& value) {
    num_bytes_ += 16;
    MeasureOutOfLine(value);
  }

  void MeasureOutOfLine(const ::fuchsia::bluetooth::le::ScanData& value) {
    int32_t max_ordinal = 0;
    if (value.has_tx_power()) {
      max_ordinal = 1;
    }
    if (value.has_appearance()) {
      max_ordinal = 2;
    }
    if (value.has_service_uuids()) {
      num_bytes_ += 16;
      num_bytes_ += FIDL_ALIGN(value.service_uuids().size() * 16);
      max_ordinal = 3;
    }
    if (value.has_service_data()) {
      num_bytes_ += 16;
      for (const auto& service_data_elem : value.service_data()) {
        Measure(service_data_elem);
      }
      max_ordinal = 4;
    }
    if (value.has_manufacturer_data()) {
      num_bytes_ += 16;
      for (const auto& manufacturer_data_elem : value.manufacturer_data()) {
        Measure(manufacturer_data_elem);
      }
      max_ordinal = 5;
    }
    if (value.has_uris()) {
      num_bytes_ += 16;
      for (const auto& uris_elem : value.uris()) {
        num_bytes_ += 16;
        num_bytes_ += FIDL_ALIGN(uris_elem.length());
      }
      max_ordinal = 6;
    }
    if (value.has_timestamp()) {
      num_bytes_ += 8;
      max_ordinal = 7;
    }
    num_bytes_ += 8 * max_ordinal;
  }

  void Measure(const ::fuchsia::bluetooth::le::ServiceData& value) {
    num_bytes_ += FIDL_ALIGN(32);
    MeasureOutOfLine(value);
  }

  void MeasureOutOfLine(const ::fuchsia::bluetooth::le::ServiceData& value) {
    num_bytes_ += FIDL_ALIGN(value.data.size() * 1);
  }

  void Measure(const ::fuchsia::bluetooth::PeerId& value) {
    num_bytes_ += FIDL_ALIGN(8);
  }

  void Measure(const ::fuchsia::bluetooth::Uuid& value) {
    num_bytes_ += FIDL_ALIGN(16);
  }

  Size Done() {
    if (maxed_out_) {
      return Size(ZX_CHANNEL_MAX_MSG_BYTES, ZX_CHANNEL_MAX_MSG_HANDLES);
    }
    return Size(num_bytes_, num_handles_);
  }

private:
  void MaxOut() { maxed_out_ = true; }

  bool maxed_out_ = false;
  int64_t num_bytes_ = 0;
  int64_t num_handles_ = 0;
};

}  // namespace


Size Measure(const ::fuchsia::bluetooth::le::Peer& value) {
  MeasuringTape tape;
  tape.Measure(value);
  return tape.Done();
}



}  // le
}  // bluetooth
}  // fuchsia
}  // measure_tape

